package kassiopeia.agent.seda.stage;

import kassiopeia.agent.seda.config.State;
import kassiopeia.agent.seda.event.EventQueue;
import kassiopeia.agent.seda.threads.PoolSizeStrategy;
import kassiopeia.agent.seda.threads.StagePool;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

import java.util.concurrent.TimeUnit;

@Configurable(dependencyCheck = true)
public class Controller implements Runnable {

    private final Logger log = Logger.getLogger(Controller.class);
    private StagePool stagePool;
    private final EventQueue input;
    private State state = State.STOPPED;
    private final String PLUGIN_INSTANCE_ID;

    @Autowired
    private PoolSizeStrategy poolSizeStrategy;

    public Controller(EventQueue input, String pluginInstanceId) {
        this.input = input;
        this.PLUGIN_INSTANCE_ID = pluginInstanceId;
    }

    @Override
    public void run() {
        state = State.RUNNING;
        while (state == State.RUNNING) {
            poolSizeStrategy.managePoolSize(stagePool, input);
            sleepMillis(poolSizeStrategy.getSleepPeriod());
            log.info(PLUGIN_INSTANCE_ID + ": queue size = " + input.size() + ", pool size = " + stagePool.getPoolSize());
        }
        state = State.STOPPED;
    }

    private void sleepMillis(long millis) {
        try {
            TimeUnit.MILLISECONDS.sleep(millis);
        } catch (InterruptedException ie) {
            log.error(ie, ie);
        }
    }

    public void setStagePool(StagePool stagePool) {
        this.stagePool = stagePool;
    }

    public PoolSizeStrategy getPoolSizeStrategy() {
        return this.poolSizeStrategy;
    }

    public void stop() {
        this.state = State.TERMINATING;
    }

    public State getState() {
        return state;
    }
}
